#ifndef UNION_EXT_H
#define UNION_EXT_H

#include "extension.h"
#include <stdio.h>
#include <stdbool.h>
#include <stdarg.h>

// 定义联合体类型（通用值容器）
typedef union {
    int int_val;
    float float_val;
    bool bool_val;
    char char_val;
} Variant;

// 定义联合体类型标签（记录当前存储的类型）
typedef enum {
    TYPE_INT,
    TYPE_FLOAT,
    TYPE_BOOL,
    TYPE_CHAR
} VariantType;

// 带类型标签的联合体包装器
typedef struct {
    Variant data;
    VariantType type;
} TaggedVariant;

// 初始化函数（基础函数）
static inline void TaggedVariant_init(TaggedVariant* self, VariantType type) {
    self->type = type;
}

// 扩展函数1：设置值（根据类型）
DEFINE_EXTENSION(TaggedVariant, set_value, void, ...);

// 扩展函数2：获取值的字符串描述
DEFINE_EXTENSION(TaggedVariant, to_string, const char*);

// 扩展函数3：打印当前值
DEFINE_EXTENSION(TaggedVariant, print, void);

// 实现扩展函数
void TaggedVariant_set_value(TaggedVariant* self, ...) {
    va_list args;
    va_start(args, self);

    switch (self->type) {
        case TYPE_INT:
            self->data.int_val = va_arg(args, int);
            break;
        case TYPE_FLOAT:
            self->data.float_val = (float)va_arg(args, double); // 注意float提升为double
            break;
        case TYPE_BOOL:
            self->data.bool_val = va_arg(args, int); // bool在va_arg中用int传递
            break;
        case TYPE_CHAR:
            self->data.char_val = (char)va_arg(args, int); // char提升为int
            break;
    }

    va_end(args);
}

const char* TaggedVariant_to_string(TaggedVariant* self) {
    static char buf[50]; // 静态缓冲区，仅用于演示

    switch (self->type) {
        case TYPE_INT:
            snprintf(buf, sizeof(buf), "整数: %d", self->data.int_val);
            break;
        case TYPE_FLOAT:
            snprintf(buf, sizeof(buf), "浮点数: %.2f", self->data.float_val);
            break;
        case TYPE_BOOL:
            snprintf(buf, sizeof(buf), "布尔值: %s", self->data.bool_val ? "真" : "假");
            break;
        case TYPE_CHAR:
            snprintf(buf, sizeof(buf), "字符: '%c'", self->data.char_val);
            break;
        default:
            snprintf(buf, sizeof(buf), "未知类型");
    }

    return buf;
}

void TaggedVariant_print(TaggedVariant* self) {
    printf("Variant: %s\n", EXTEND(TaggedVariant, self, to_string));
}

#endif // UNION_EXT_H
